package com.kakarote.examine.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.kakarote.common.log.annotation.OperateLog;
import com.kakarote.common.log.entity.OperationLog;
import com.kakarote.common.log.entity.OperationResult;
import com.kakarote.common.log.enums.ApplyEnum;
import com.kakarote.common.log.enums.BehaviorEnum;
import com.kakarote.common.log.enums.OperateObjectEnum;
import com.kakarote.common.log.enums.OperateTypeEnum;
import com.kakarote.core.common.Result;
import com.kakarote.core.common.enums.DateFilterEnum;
import com.kakarote.core.entity.BasePage;
import com.kakarote.core.entity.UserInfo;
import com.kakarote.core.exception.CrmException;
import com.kakarote.core.feign.admin.entity.ExamineEmailBO;
import com.kakarote.core.feign.examine.entity.ExamineFlowFinalBO;
import com.kakarote.core.feign.examine.entity.ExamineInfoVo;
import com.kakarote.core.feign.oa.entity.OaSearchBO;
import com.kakarote.core.utils.UserUtil;
import com.kakarote.examine.constant.ExamineCodeEnum;
import com.kakarote.examine.entity.BO.*;
import com.kakarote.examine.entity.PO.ExamineRecordEmail;
import com.kakarote.examine.entity.VO.*;
import com.kakarote.examine.service.IExamineRecordLogService;
import com.kakarote.examine.service.IExamineRecordService;
import com.kakarote.examine.service.ISuperExamineService;
import com.kakarote.examine.service.ISuperExamineToDoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Slf4j
@RestController
@RequestMapping("/examineSuperExamines")
@Api(tags = "超级审批业务接口")
public class SuperExamineController {

    @Autowired
    private ISuperExamineService superExamineService;

    @Autowired
    private ISuperExamineToDoService iSuperExamineToDoService;

    @Autowired
    private IExamineRecordService iExamineRecordService;

    @Autowired
    private IExamineRecordLogService iExamineRecordLogService;


    @ApiOperation("新建分组")
    @PostMapping(value = "/addExamineGroup")
    @OperateLog(apply = ApplyEnum.OFFICE_MANAGEMENT, behavior = BehaviorEnum.SAVE, object = OperateObjectEnum.APPROVAL_FLOW, type = OperateTypeEnum.SETTING)
    public Result addExamineGroup(@RequestBody ExamineGroupBO examineGroupBO) {
        OperationLog operationLog = superExamineService.addOrUpdateExamineGroup(examineGroupBO);
        return OperationResult.ok(operationLog);
    }

    @ApiOperation("编辑分组")
    @PostMapping(value = "/updateExamineGroup")
    @OperateLog(apply = ApplyEnum.OFFICE_MANAGEMENT, behavior = BehaviorEnum.UPDATE, object = OperateObjectEnum.APPROVAL_FLOW, type = OperateTypeEnum.SETTING)
    public Result updateExamineGroup(@RequestBody ExamineGroupBO examineGroupBO) {
        OperationLog operationLog = superExamineService.addOrUpdateExamineGroup(examineGroupBO);
        return OperationResult.ok(operationLog);
    }

    @ApiOperation("删除分组")
    @PostMapping(value = "/delExamineGroup")
    @OperateLog(apply = ApplyEnum.OFFICE_MANAGEMENT, behavior = BehaviorEnum.DELETE, object = OperateObjectEnum.APPROVAL_FLOW, type = OperateTypeEnum.SETTING)
    public Result delExamineGroup(@RequestBody List<Long> groupId) {
        List<OperationLog> operationLogList = superExamineService.delExamineGroup(groupId);
        return OperationResult.ok(operationLogList);
    }

    @ApiOperation("查询分组-办公审批流查询")
    @PostMapping(value = "/queryExamineGroup")
    public Result<List<ExamineGroupVO>> queryExamineGroup(@RequestBody ExaminePageBO examinePageBo) {
        List<ExamineGroupVO> examineGroupVOList = superExamineService.queryExamineGroup(examinePageBo);
        return Result.ok(examineGroupVOList);
    }

    @ApiOperation("查询分组-不含高级配置")
    @PostMapping(value = "/querySimplyExamineGroup")
    public Result<List<ExamineGroupVO>> querySimplyExamineGroup(@RequestBody ExaminePageBO examinePageBo) {
        List<ExamineGroupVO> examineGroupVOList = superExamineService.querySimplyExamineGroup(examinePageBo);
        return Result.ok(examineGroupVOList);
    }

    @ApiOperation("最近使用的审批-首页")
    @PostMapping(value = "/recentlyUsedExamineList")
    public Result<List<ExamineVO>> recentlyUsedExamineList() {
        List<ExamineVO> examineVOList = superExamineService.recentlyUsedExamineList();
        return Result.ok(examineVOList);
    }

    @ApiOperation("申请列表-有分组")
    @PostMapping(value = "/applyList")
    public Result<List<SupperExamineApplyVO>> applyList() {
        List<SupperExamineApplyVO> examineVOList = superExamineService.applyList();
        return Result.ok(examineVOList);
    }

    @ApiOperation("申请列表-无分组")
    @PostMapping(value = "/uni/applyList")
    public Result<List<ExamineVO>> uniApplyList() {
        List<ExamineVO> examineVOList = superExamineService.uniApplyList();
        return Result.ok(examineVOList);
    }

    @ApiOperation("根据名称查询审批流-首页搜索")
    @PostMapping(value = "/querySuperExamineInfoByName")
    public Result<BasePage<OaSuperExamineVO>> querySuperExamineInfoByName(@RequestBody OaSearchBO oaSearchBO) {
        BasePage<OaSuperExamineVO> examineVOList = superExamineService.querySuperExamineInfoByName(oaSearchBO);
        return Result.ok(examineVOList);
    }

    @ApiOperation("根据名称查询审批流-申请页签使用")
    @PostMapping(value = "/querySuperExamineByName")
    public Result<List<ExamineVO>> querySuperExamineByName(@RequestBody SuperExamineSearchBO superExamineSearchBO) {
        List<ExamineVO> examineVOList = superExamineService.querySuperExamineByName(superExamineSearchBO);
        return Result.ok(examineVOList);
    }

    @ApiOperation("待办查询-首页")
    @PostMapping(value = "/queryBackLogInfo")
    public Result<SuperExamineBackLogVO> queryBackLogInfo() {
        SuperExamineBackLogVO superExamineBackLogVO = superExamineService.queryBackLogInfo();
        return Result.ok(superExamineBackLogVO);
    }

    @ApiOperation("追踪查询-首页")
    @PostMapping(value = "/queryTraceInfo")
    public Result<SuperExamineTraceVO> queryTraceInfo() {
        SuperExamineTraceVO superExamineTraceVO = superExamineService.queryTraceInfo();
        return Result.ok(superExamineTraceVO);
    }


    @ApiOperation("报表---统计头信息")
    @PostMapping(value = "/getExamineReportInfo")
    public Result<SuperExamineReportHeadVO> getExamineReportInfo(@RequestBody SuperExamineReportSearchBO searchBO) {
        searchBO.setDateFilter(DateFilterEnum.MONTH);
        SuperExamineReportHeadVO ret = superExamineService.getExamineReportInfo(searchBO);
        if (ObjectUtil.isEmpty(ret)) {
            ret = new SuperExamineReportHeadVO();
        }
        ret.setYear(LocalDateTime.now().getYear());
        ret.setMonth(LocalDateTime.now().getMonthValue());
        return Result.ok(ret);
    }

    @ApiOperation("报表---列表信息")
    @PostMapping(value = "/getExamineReportList")
    public Result<BasePage<SuperExamineReportListVO>> getExamineReportList(@RequestBody SuperExamineReportSearchBO searchBO) {
        BasePage<SuperExamineReportListVO> ret = superExamineService.getExamineReportList(searchBO);
        return Result.ok(ret);
    }

    @ApiOperation("报表---导出")
    @PostMapping(value = "/getExamineReporExport")
    public void getExamineReporExport(@RequestBody SuperExamineReportSearchBO searchBO, HttpServletResponse response) {
        superExamineService.getExamineReporExport(response, searchBO);
    }

    @PostMapping("/useExamineEmailSend")
    @ApiOperation("邮件催办进行发送邮件")
    public Result<ExamineInfoVo> useExamineEmailSend(@RequestParam("examineRecordId") @NotNull Long examineRecordId) {
        return Result.ok();
    }

    @PostMapping("/useExamineEmailTokenForExamineRecordList")
    @ApiOperation("通过邮件打开的链接获取审批详情")
    public Result<SuperExamineRecordVO> useExamineEmailTokenForExamineRecordList(@RequestParam("emailToken") @NotNull String emailToken) {
        ExamineRecordEmail examineRecordEmail = superExamineService.getEmailToken(emailToken);
        //校验token
        if (ObjectUtil.isEmpty(emailToken) || ObjectUtil.isEmpty(examineRecordEmail)) {
            return Result.error(ExamineCodeEnum.EXAMINE_FROM_EMAIL_OUT_TOKEN_ERROR);
        }
        Long userId = examineRecordEmail.getUserId();
        Long recordId = examineRecordEmail.getRecordId();
        String outExamineEmail = examineRecordEmail.getToEmail();
        Integer examineRecordTypeIdStyle = examineRecordEmail.getExamineRecordTypeIdStyle();
        SuperExamineRecordVO superExamineRecordVO = new SuperExamineRecordVO();
        try {
            //设置用户信息
            UserInfo userInfo = UserUtil.setUser(userId);
            //设置用户信息
            superExamineRecordVO = iSuperExamineToDoService.queryExamineRecordList(recordId, userId, outExamineEmail, examineRecordTypeIdStyle);
            superExamineRecordVO.setIsSkip(0);
            superExamineRecordVO.setIsRestore(0);
            //设置已读
            iSuperExamineToDoService.setRecordLogRead(recordId, userId, outExamineEmail, examineRecordTypeIdStyle);
        } catch (Exception e) {
            log.error("通过邮件打开的链接获取审批详情异常：", e);
            return Result.error(new CrmException(3000015, "请联系系统管理员！"));
        } finally {
            //无登录状态下清理设置的用户信息
            UserUtil.removeUser();
        }
        return Result.ok(superExamineRecordVO);
    }

    @PostMapping("/useExamineEmailTokenForExamineRecordLog")
    @ApiOperation("通过邮件打开的链接获取审批记录")
    public Result<List<ExamineRecordLogVO>> useExamineEmailTokenForExamineRecordLog(@RequestParam("emailToken") @NotNull String emailToken) {
        ExamineRecordEmail examineRecordEmail = superExamineService.getEmailToken(emailToken);
        //校验token
        if (ObjectUtil.isEmpty(emailToken) || ObjectUtil.isEmpty(examineRecordEmail)) {
            return Result.error(ExamineCodeEnum.EXAMINE_FROM_EMAIL_OUT_TOKEN_ERROR);
        }
        Long userId = examineRecordEmail.getUserId();
        Long recordId = examineRecordEmail.getRecordId();
        List<ExamineRecordLogVO> data;
        try {
            //设置用户信息
            UserUtil.setUser(userId);
            data = iExamineRecordLogService.queryExamineRecordLog(recordId, userId.toString(), examineRecordEmail.getExamineRecordTypeId());
        } catch (Exception e) {
            return Result.error(new CrmException(3000015, "请联系系统管理员！"));
        } finally {
            //无登录状态下清理设置的用户信息
            UserUtil.removeUser();
        }
        return Result.ok(data);
    }

    @PostMapping("/useExamineEmailTokenForAuditExamine")
    @ApiOperation("通过邮件打开的链接进行审批")
    public Result auditExamine(@RequestBody ExamineBO examineBO) {
        String emailToken = examineBO.getEmailToken();
        ExamineRecordEmail examineRecordEmail = superExamineService.getEmailToken(emailToken);
        //校验审核状态
        if (ObjectUtil.isEmpty(examineBO.getStatus())) {
            return Result.error(ExamineCodeEnum.EXAMINE_PARAMS_ERROR);
        }
        //校验token
        if (ObjectUtil.isEmpty(emailToken) || ObjectUtil.isEmpty(examineRecordEmail)) {
            return Result.error(ExamineCodeEnum.EXAMINE_FROM_EMAIL_OUT_TOKEN_ERROR);
        }
        //添加校验审批意见
        if (Objects.equals(2, examineBO.getStatus()) && ObjectUtil.isEmpty(examineBO.getRemarks())) {
            return Result.error(ExamineCodeEnum.EXAMINE_PASS_OR_CANCEL_REMART_NOT_EMPTY_ERROR);
        }
        try {
            //设置用户信息
            Long userId = examineRecordEmail.getUserId();
            UserUtil.setUser(userId);

            examineBO.setRecordId(examineRecordEmail.getRecordId());
            examineBO.setTypeId(examineRecordEmail.getExamineRecordTypeId());
            if (ObjectUtil.isNotEmpty(examineRecordEmail.getExamineRecordTypeIdStyle()) && examineRecordEmail.getExamineRecordTypeIdStyle().equals(2)) {
                examineBO.setUserEmail(examineRecordEmail.getToEmail());
            }
            examineBO.setPassFlag(1);
            examineBO.setStatus(examineBO.getStatus());
            examineBO.setRemarks(examineBO.getRemarks());
            iExamineRecordService.auditExamine(examineBO);
        } catch (Exception e) {
            log.error("通过邮件打开的链接进行审批异常：", e);
            return Result.error(new CrmException(3000015, "请联系系统管理员！"));
        } finally {
            //无登录状态下清理设置的用户信息
            UserUtil.removeUser();
        }
        return Result.ok();
    }

    @PostMapping("/queryTimeOutRecordList")
    @ApiOperation("查询超时未处理recordList")
    public Result<List<Long>> queryTimeOutRecordList() {
        List<Long> recordIdList = superExamineService.queryTimeOutRecordList();
        return Result.ok(recordIdList);
    }




    @ApiOperation("报表---列表下钻信息")
    @PostMapping(value = "/getExamineReportSubList")
    public Result<BasePage<com.kakarote.core.feign.oa.entity.ExamineVO>> getExamineReportSubList(@RequestBody SuperExamineReportSubSearchBO searchBO) {
        BasePage<com.kakarote.core.feign.oa.entity.ExamineVO> ret = superExamineService.getExamineReportSubList(searchBO);
        return Result.ok(ret);
    }

    @ApiOperation("邮件审批---设置邮件审批有效性")
    @PostMapping(value = "/set/email/audit/valid")
    public Result setEmailAuditValid(@RequestBody ExamineEmailBO examineBO) {
        superExamineService.setEmailAuditValid(examineBO);
        return Result.ok();
    }

    @ApiOperation("邮件审批---根据key获取邮件审批有效性")
    @PostMapping(value = "/get/email/audit/valid")
    public Result<ExamineEmailBO> getEmailAuditValid(@RequestBody ExamineEmailBO examineBO) {
        ExamineRecordEmail emailToken = superExamineService.getEmailToken(examineBO.getEmailToken());
        return Result.ok(BeanUtil.copyProperties(emailToken, ExamineEmailBO.class));
    }

    @ApiOperation("设置节点自选信息")
    @PostMapping("/set/node/optional")
    public Result setNodeOptional(@RequestBody ExamineFlowFinalBO flowFinalBO) {
        superExamineService.setNodeOptional(flowFinalBO);
        return Result.ok();
    }

}


